package uk.ac.sanger;

import org.xml.sax.*;             // The main SAX package
import org.xml.sax.helpers.*;     // SAX helper classes
import java.io.*;                 // For reading the input file
import java.util.*;               // Hashtable, lists, and so on


public class OrganismXMLParser extends org.xml.sax.helpers.DefaultHandler {
	public static void main(String[] args)throws IOException, SAXException {
		
		// Create the parser we'll use.  The parser implementation is a 
        // Xerces class, but we use it only through the SAX XMLReader API
        org.xml.sax.XMLReader parser=new org.apache.xerces.parsers.SAXParser();

        // Specify that we don't want validation.  This is the SAX2
        // API for requesting parser features.  Note the use of a
        // globally unique URL as the feature name.  Non-validation is
        // actually the default, so this line isn't really necessary.
        parser.setFeature("http://xml.org/sax/features/validation", false);

        // Instantiate this class to provide handlers for the parser and 
        // tell the parser about the handlers
        OrganismXMLParser handler = new OrganismXMLParser();
        parser.setContentHandler(handler);
        parser.setErrorHandler(handler);
       
        // Create an input source that describes the file to parse.
        // Then tell the parser to parse input from that source
        org.xml.sax.InputSource input=new InputSource(new FileReader("coordinatesystem.xml"));
        parser.parse(input);
		}
    

	Map nameToAttributes;  // Map from servlet name to attributes

    StringBuffer accumulator;                         // Accumulate text
    String organism; // Remember text
    Attributes my_attributes;
   
    // Called at the beginning of parsing.  We use it as an init() method
    public void startDocument() {
        accumulator = new StringBuffer();
        nameToAttributes = new HashMap();
    }

    // When the parser encounters plain text (not XML elements), it calls
    // this method, which accumulates them in a string buffer.
    // Note that this method may be called multiple times, even with no
    // intervening elements.
    public void characters(char[] buffer, int start, int length) {
        accumulator.append(buffer, start, length);
    }

    // At the beginning of each new element, erase any accumulated text.
    public void startElement(String namespaceURL, String localName,
                             String qname, Attributes attributes) {
        accumulator.setLength(0);
        my_attributes=attributes;
    }

    // Take special action when we reach the end of selected elements.
    // Although we don't use a validating parser, this method does assume
    // that the web.xml file we're parsing is valid.
    public void endElement(String namespaceURL, String localName, String qname)
    {
    	
        if (localName.equals("COORDINATES")) {        // Store element name
            organism = accumulator.toString().trim();
            //store list of attributes
            List attributes = (List)nameToAttributes.get(organism);
            if (attributes == null) {
                    attributes = new ArrayList();
                    //store element
                    nameToAttributes.put(organism, attributes);
                }
            if (my_attributes.getLocalName(0) != null)
            {
            	for (int i = 0; i < my_attributes.getLength(); i++) {
             		attributes.add(my_attributes.getLocalName(i) + " : " + my_attributes.getValue(i)); 
              		}
            	}
            
        }   
              
    }

    // Called at the end of parsing.  Used here to print our results.
    public void endDocument() {
        List OrganismNames = new ArrayList(nameToAttributes.keySet());
        Collections.sort(OrganismNames);
        System.out.println("No of lines : "+ OrganismNames.size() + "\n--------"); 
        for(Iterator iterator = OrganismNames.iterator(); iterator.hasNext();) {
            String name = (String)iterator.next();
            
            List attributes = (List)nameToAttributes.get(name);
           // Collections.sort(attributes);
            System.out.println("\nNAME : "+ name + "\n--------");     
            
            if (attributes != null) {
            	
            	for(Iterator i = attributes.iterator(); i.hasNext(); ) 
                {
            		System.out.println( i.next());
                }    
            }
          }
    }

    // Issue a warning
    public void warning(SAXParseException exception) {
        System.err.println("WARNING: line " + exception.getLineNumber() + ": "+
                           exception.getMessage());
    }

    // Report a parsing error
    public void error(SAXParseException exception) {
        System.err.println("ERROR: line " + exception.getLineNumber() + ": " +
                           exception.getMessage());
    }

    // Report a non-recoverable error and exit
    public void fatalError(SAXParseException exception) throws SAXException {
        System.err.println("FATAL: line " + exception.getLineNumber() + ": " +
                           exception.getMessage());
        throw(exception);
    }
}
